<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>聊天助手 - Melon</title>
    <script src="https://cdn.socket.io/4.7.2/socket.io.min.js"></script>
    <!-- 添加 Marked 库用于解析 Markdown -->
    <script src="https://cdn.jsdelivr.net/npm/marked@4.3.0/marked.min.js"></script>
    <!-- 添加代码高亮支持 -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/highlight.js@11.7.0/styles/github.min.css">
    <script src="https://cdn.jsdelivr.net/npm/highlight.js@11.7.0/highlight.min.js"></script>
    <style>
        :root {
            --primary-color: #4a6ee0;
            --light-bg: #f5f7fb;
            --dark-text: #333;
            --user-bubble: #e1f5fe;
            --bot-bubble: #f0f2ff;
            --border-radius: 18px;
            --code-bg: #f6f8fa;
            --code-border: #ddd;
        }

        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background-color: var(--light-bg);
            color: var(--dark-text);
            line-height: 1.6;
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
            height: 100vh;
            display: flex;
            flex-direction: column;
        }

        header {
            padding: 15px 0;
            text-align: center;
            border-bottom: 1px solid #eee;
            margin-bottom: 20px;
        }

        header h1 {
            font-size: 24px;
            color: var(--primary-color);
            font-weight: 600;
        }

        #chat-container {
            flex: 1;
            display: flex;
            flex-direction: column;
            max-width: 800px;
            margin: 0 auto;
            width: 100%;
            box-shadow: 0 5px 15px rgba(0, 0, 0, 0.08);
            border-radius: 12px;
            background: white;
            overflow: hidden;
        }

        #chat-box {
            flex: 1;
            padding: 20px;
            overflow-y: auto;
            background-color: white;
        }

        .message {
            max-width: 80%;
            margin-bottom: 15px;
            clear: both;
            position: relative;
            animation: fadeIn 0.3s ease;
            display: flex;
            align-items: flex-start;
        }

        @keyframes fadeIn {
            from {
                opacity: 0;
                transform: translateY(10px);
            }
            to {
                opacity: 1;
                transform: translateY(0);
            }
        }

        .user-message {
            float: right;
            margin-left: auto;
            flex-direction: row-reverse;
        }

        .assistant-message {
            float: left;
            margin-right: auto;
        }

        .avatar {
            width: 36px;
            height: 36px;
            border-radius: 50%;
            margin: 0 8px;
            background-size: cover;
            background-position: center;
            flex-shrink: 0;
        }

        .user-avatar {
            background-color: var(--primary-color);
            display: flex;
            align-items: center;
            justify-content: center;
        }

        .user-avatar svg {
            width: 18px;
            height: 18px;
            fill: white;
        }

        .assistant-avatar {
            background-color: #dff0ff;
            display: flex;
            align-items: center;
            justify-content: center;
        }

        .assistant-avatar svg {
            width: 20px;
            height: 20px;
            fill: var(--primary-color);
        }

        .message-content {
            padding: 12px 16px;
            border-radius: var(--border-radius);
            display: inline-block;
            position: relative;
            max-width: 100%;
            word-wrap: break-word;
        }

        .user-message .message-content {
            background-color: var(--primary-color);
            color: white;
            border-radius: var(--border-radius) var(--border-radius) 0 var(--border-radius);
            margin-right: 4px;
        }

        .assistant-message .message-content {
            background-color: var(--bot-bubble);
            color: var(--dark-text);
            border-radius: 0 var(--border-radius) var(--border-radius) var(--border-radius);
            margin-left: 4px;
        }

        /* Markdown 样式 */
        .message-content p {
            margin-bottom: 10px;
        }

        .message-content p:last-child {
            margin-bottom: 0;
        }

        .message-content h1,
        .message-content h2,
        .message-content h3,
        .message-content h4,
        .message-content h5,
        .message-content h6 {
            margin-top: 16px;
            margin-bottom: 8px;
            font-weight: 600;
        }

        .message-content ul,
        .message-content ol {
            margin-left: 24px;
            margin-bottom: 10px;
        }

        .message-content a {
            color: #0366d6;
            text-decoration: none;
        }

        .message-content a:hover {
            text-decoration: underline;
        }

        .message-content img {
            max-width: 100%;
            border-radius: 4px;
        }

        .message-content pre {
            background-color: var(--code-bg);
            border-radius: 6px;
            padding: 12px;
            overflow-x: auto;
            margin: 10px 0;
            border: 1px solid var(--code-border);
        }

        .message-content code {
            font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
            font-size: 14px;
            padding: 2px 5px;
            background-color: var(--code-bg);
            border-radius: 3px;
        }

        .message-content pre code {
            padding: 0;
            background-color: transparent;
        }

        .user-message .message-content code,
        .user-message .message-content pre {
            background-color: rgba(255, 255, 255, 0.1);
            border-color: rgba(255, 255, 255, 0.2);
        }

        .user-message .message-content a {
            color: #a7cdff;
        }

        .sender-name {
            font-size: 0.8em;
            color: #888;
            margin-bottom: 4px;
        }

        #input-area {
            padding: 15px;
            background-color: white;
            border-top: 1px solid #eee;
            display: flex;
            align-items: center;
        }

        #user-input {
            flex: 1;
            padding: 12px 16px;
            border: 1px solid #ddd;
            border-radius: 24px;
            font-size: 16px;
            outline: none;
            transition: border 0.3s, box-shadow 0.3s;
        }

        #user-input:focus {
            border-color: var(--primary-color);
            box-shadow: 0 0 0 2px rgba(74, 110, 224, 0.2);
        }

        #send-button {
            background-color: var(--primary-color);
            color: white;
            border: none;
            border-radius: 50%;
            width: 46px;
            height: 46px;
            margin-left: 10px;
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: center;
            transition: background-color 0.3s;
        }

        #send-button:hover {
            background-color: #3a5dbe;
        }

        #send-button:active {
            transform: scale(0.95);
        }

        .typing-indicator {
            display: inline-block;
            margin-left: 5px;
        }

        .typing-indicator span {
            display: inline-block;
            width: 8px;
            height: 8px;
            border-radius: 50%;
            background-color: var(--primary-color);
            opacity: 0.6;
            margin: 0 2px;
            animation: typing 1.4s infinite both;
        }

        .typing-indicator span:nth-child(2) {
            animation-delay: 0.2s;
        }

        .typing-indicator span:nth-child(3) {
            animation-delay: 0.4s;
        }

        @keyframes typing {
            0% {
                transform: translateY(0);
            }
            50% {
                transform: translateY(-5px);
            }
            100% {
                transform: translateY(0);
            }
        }

        /* 适配移动设备 */
        @media (max-width: 768px) {
            body {
                padding: 10px;
            }

            .message {
                max-width: 90%;
            }
        }
    </style>
</head>
<body>
<header>
    <h1>聊天助手 - Melon</h1>
</header>

<div id="chat-container">
    <div id="chat-box"></div>
    <div id="input-area">
        <input type="text" id="user-input" placeholder="请输入您的问题..."
               onkeypress="if(event.key === 'Enter') sendMessage()">
        <button id="send-button" onclick="sendMessage()">
            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path d="M22 2L11 13" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                <path d="M22 2L15 22L11 13L2 9L22 2Z" stroke="white" stroke-width="2" stroke-linecap="round"
                      stroke-linejoin="round"/>
            </svg>
        </button>
    </div>
</div>

<script>
    var socket = io();
    var chatBox = document.getElementById("chat-box");
    var userInput = document.getElementById("user-input");
    var sendButton = document.getElementById("send-button");
    var currentAssistantMessage = null;
    var isWaitingForResponse = false;

    // 配置 Marked 选项
    marked.setOptions({
        highlight: function(code, lang) {
            if (lang && hljs.getLanguage(lang)) {
                return hljs.highlight(code, { language: lang }).value;
            }
            return hljs.highlightAuto(code).value;
        },
        breaks: true,
        gfm: true
    });

    // 解析 Markdown 函数
    function parseMarkdown(text) {
        return marked.parse(text);
    }

    function appendMessage(sender, message, isUser) {
        var messageDiv = document.createElement("div");
        messageDiv.className = isUser ? "message user-message" : "message assistant-message";

        // 创建头像元素
        var avatarDiv = document.createElement("div");
        avatarDiv.className = isUser ? "avatar user-avatar" : "avatar assistant-avatar";

        // 添加头像图标
        if (isUser) {
            avatarDiv.innerHTML = `
                <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
                    <path d="M12 12C14.21 12 16 10.21 16 8C16 5.79 14.21 4 12 4C9.79 4 8 5.79 8 8C8 10.21 9.79 12 12 12ZM12 14C9.33 14 4 15.34 4 18V20H20V18C20 15.34 14.67 14 12 14Z"/>
                </svg>
            `;
        } else {
            avatarDiv.innerHTML = `
                <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
                    <path d="M12 2C6.48 2 2 6.48 2 12C2 17.52 6.48 22 12 22C17.52 22 22 17.52 22 12C22 6.48 17.52 2 12 2ZM17 13H13V17H11V13H7V11H11V7H13V11H17V13Z"/>
                </svg>
            `;
        }

        var messageContent = document.createElement("div");
        messageContent.className = "message-content";

        // 根据消息类型决定是否解析 Markdown
        if (isUser) {
            // 用户消息不解析 Markdown，但需要转义 HTML
            messageContent.innerHTML = escapeHtml(message);
        } else {
            // 助手消息解析 Markdown
            messageContent.innerHTML = parseMarkdown(message);

            // 应用代码高亮
            messageContent.querySelectorAll('pre code').forEach((block) => {
                hljs.highlightBlock(block);
            });
        }

        messageDiv.appendChild(avatarDiv);
        messageDiv.appendChild(messageContent);
        chatBox.appendChild(messageDiv);
        chatBox.scrollTop = chatBox.scrollHeight;

        return messageDiv;
    }

    // HTML 转义函数
    function escapeHtml(text) {
        var map = {
            '&': '&amp;',
            '<': '&lt;',
            '>': '&gt;',
            '"': '&quot;',
            "'": '&#039;'
        };
        return text.replace(/[&<>"']/g, function(m) { return map[m]; });
    }

    function createTypingIndicator() {
        var messageDiv = document.createElement("div");
        messageDiv.className = "message assistant-message";
        messageDiv.id = "typing-message";

        // 添加机器人头像
        var avatarDiv = document.createElement("div");
        avatarDiv.className = "avatar assistant-avatar";
        avatarDiv.innerHTML = `
            <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
                <path d="M12 2C6.48 2 2 6.48 2 12C2 17.52 6.48 22 12 22C17.52 22 22 17.52 22 12C22 6.48 17.52 2 12 2ZM17 13H13V17H11V13H7V11H11V7H13V11H17V13Z"/>
            </svg>
        `;

        var messageContent = document.createElement("div");
        messageContent.className = "message-content";

        var indicator = document.createElement("div");
        indicator.className = "typing-indicator";
        indicator.innerHTML = '<span></span><span></span><span></span>';

        messageContent.appendChild(indicator);
        messageDiv.appendChild(avatarDiv);
        messageDiv.appendChild(messageContent);
        chatBox.appendChild(messageDiv);
        chatBox.scrollTop = chatBox.scrollHeight;

        return messageDiv;
    }

    function removeTypingIndicator() {
        var typingIndicator = document.getElementById("typing-message");
        if (typingIndicator) {
            typingIndicator.remove();
        }
    }

    function sendMessage() {
        var message = userInput.value.trim();
        if (message === "" || isWaitingForResponse) return;

        // 禁用输入框和发送按钮
        isWaitingForResponse = true;
        userInput.disabled = true;
        sendButton.disabled = true;

        appendMessage("你", message, true);
        socket.emit("user_message", {message: message});
        userInput.value = "";

        // 显示打字指示器
        createTypingIndicator();
    }

    // 旧的单次响应监听器（保留以兼容）
    socket.on("assistant_reply", function (data) {
        removeTypingIndicator();
        appendMessage("Melon", data.message, false);
        enableInput();
    });

    // 处理流式响应片段
    socket.on("assistant_stream", function (data) {
        removeTypingIndicator();

        if (!currentAssistantMessage) {
            // 创建新的消息容器
            currentAssistantMessage = appendMessage("Melon", "", false);
        }

        // 更新消息内容 - 重新解析整个消息的 Markdown
        var messageContent = currentAssistantMessage.querySelector(".message-content");
        messageContent.innerHTML = parseMarkdown(data.full);

        // 重新应用代码高亮
        messageContent.querySelectorAll('pre code').forEach((block) => {
            hljs.highlightBlock(block);
        });

        chatBox.scrollTop = chatBox.scrollHeight;
    });

    // 处理响应完成
    socket.on("assistant_complete", function (data) {
        removeTypingIndicator();

        // 如果没有流式更新创建消息（兜底逻辑）
        if (!currentAssistantMessage) {
            appendMessage("Melon", data.message, false);
        }

        // 重置当前消息
        currentAssistantMessage = null;

        // 重新启用输入框和发送按钮
        enableInput();
    });

    function enableInput() {
        isWaitingForResponse = false;
        userInput.disabled = false;
        sendButton.disabled = false;
        userInput.focus();
    }

    // 添加初始欢迎消息
    window.onload = function () {
        appendMessage("Melon", "# 欢迎使用 Melon 聊天助手！\n\n我可以帮助回答您的问题，支持 **Markdown** 格式输出：\n\n- 支持列表和表格\n- 支持 *斜体* 和 **粗体**\n- 支持 `代码` 和代码块\n\n```python\nprint('Hello, World!')\n```\n\n有什么我可以帮您的吗？", false);
        userInput.focus();
    };
</script>
</body>
</html>